package com.nan.gbd.library.extractor;

import android.media.MediaExtractor;
import android.media.MediaFormat;

import com.nan.gbd.library.codec.MediaCodecConstant;
import com.nan.gbd.library.utils.Logger;

import java.nio.ByteBuffer;

/**
 * 视频解码线程
 */
public class VideoExtractorThread extends Extractor {
    ByteBuffer videoByteBuffer;

    public VideoExtractorThread(String filePath) {
        super(filePath);
    }

    @Override
    public void run() {
        // 获取视频所在轨道
        int videoTrackIndex = getTrackIndex(mediaExtractor, "video/");
        if (videoTrackIndex < 0) return;

        MediaFormat mediaFormat = mediaExtractor.getTrackFormat(videoTrackIndex);
        maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);//获取视频的输出缓存的最大大小
        if (extractorListener != null) {
            extractorListener.videoAspect(mediaFormat);
        }
        mediaExtractor.selectTrack(videoTrackIndex);
        videoByteBuffer = ByteBuffer.allocate(maxInputSize);
        startMs = System.currentTimeMillis();

        while (!Thread.interrupted()) {
            if (!isPlaying) {
                try {
                    sleep(50);
                    continue;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (isPlaying) {
                // 暂停-恢复
                if (isPause) {
                    continue;
                }
                // 将资源传递到解码器
                extractorMediaData();
                seekToUs = -1;
            }
        }
        // 释放解码器
        mediaExtractor.release();
    }


    /**
     * 解复用，得到需要解码的数据
     *
     * @return
     */
    @Override
    protected void extractorMediaData() {
        if (MediaCodecConstant.videoStop) return;
        if (seekToUs != -1) {
            mediaExtractor.seekTo(seekToUs, MediaExtractor.SEEK_TO_NEXT_SYNC);
        }
        videoByteBuffer.position(0);
        int sampleSize = mediaExtractor.readSampleData(videoByteBuffer, 0);
        if (sampleSize < 0) {
            Logger.e("视频 数据播放完了 end of stream");
            MediaCodecConstant.videoStop = true;
            if (extractorListener != null && MediaCodecConstant.audioStop) {
                extractorListener.endStream();
            }
        } else {
            byte[] buffer = new byte[sampleSize];
            videoByteBuffer.get(buffer, 0, sampleSize);
            long pts = mediaExtractor.getSampleTime() / 1000;
            // 延时解码，同步
            decodeDelay(pts);
            if (extractorListener != null) {
                extractorListener.videoDatas(buffer, pts);
            }
            videoByteBuffer.clear();
            mediaExtractor.advance();
        }
    }


    /**
     * 解码延时
     *
     * @param ptsTimes
     */
    private void decodeDelay(long ptsTimes) {
        long systemTimes = System.currentTimeMillis() - startMs;
        long timeDifference = ptsTimes - systemTimes;
        if (timeDifference > 0) {
            try {
                Logger.e("===video=====decodeDelay===" + timeDifference);
                sleep(timeDifference);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void release() {
        super.release();
        videoByteBuffer.clear();
        videoByteBuffer = null;
    }
}
